﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace BF
{
    public static class ConfigHelper
    {
        private static readonly string _configPath = "Config/Bean/";

        private static readonly Dictionary<string, IList> _configDic = new Dictionary<string, IList>();

        public static int GetConfigCount<T>(string variant = null) where T : IConfigBean
        {
            IList list = DoGetConfig<T>(variant);
            return list.Count;
        }

        public static T GetConfig<T>(int index, string variant = null) where T : IConfigBean
        {
            IList list = DoGetConfig<T>(variant);

            if (index < 0 || index >= list.Count)
            {
                string message = $"[ConfigHelper] GetConfig<{typeof(T).Name}>, index:{index}, maxCount:{list.Count}";
                Debug.LogError(message);
#if UNITY_EDITOR
                throw new ArgumentOutOfRangeException("index", message);
#endif
                return default;
            }
            return (T)list[index];
        }

        public static IReadOnlyList<T> GetConfig<T>() where T : IConfigBean
        {
            IList list = DoGetConfig<T>(null);
            IReadOnlyList<T> configList = list as IReadOnlyList<T>;
            return configList;
        }

        public static IReadOnlyList<T> GetConfig<T>(string variant = null) where T : IConfigBean
        {
            IList list = DoGetConfig<T>(variant);
            IReadOnlyList<T> configList = list as IReadOnlyList<T>;
            return configList;
        }

        public static void LoadConfig<T>(string variant = null) where T : IConfigBean
        {
            string typeName = GetTypeName<T>(variant);

            if (_configDic.ContainsKey(typeName))
            {
                return;
            }
            try
            {
                string path = _configPath + typeName;
                TextAsset textAsset = Resources.Load<TextAsset>(path);
                byte[] bytes = textAsset.bytes;
                Resources.UnloadAsset(textAsset);
                List<T> configList = SerializeUtil.Deserialize<List<T>>(bytes);
                _configDic.Add(typeName, configList.ToArray());
                configList.Clear();
                configList = null;
            }
            catch (Exception e)
            {
                string message = $"[ConfigHelper] LoadConfig<{typeName}>, {e}";
                Debug.LogError(message);
#if UNITY_EDITOR
                throw e;
#endif
            }
        }

        public static void UnloadConfig<T>(string variant = null)
        {
            string typeName = GetTypeName<T>(variant);

            if (!_configDic.ContainsKey(typeName))
            {
                return;
            }
            _configDic[typeName].Clear();
            _configDic.Remove(typeName);
        }

        public static void UnloadAllConfig()
        {
            foreach (var pair in _configDic)
            {
                pair.Value.Clear();
            }
            _configDic.Clear();
        }

        private static string GetTypeName<T>(string variant)
        {
            string type = typeof(T).ToString();
            if (!string.IsNullOrEmpty(variant))
            {
                type = type.Replace("Bean", variant + "Bean");
            }
            return type;
        }

        private static IList DoGetConfig<T>(string variant) where T : IConfigBean
        {
            string typeName = GetTypeName<T>(variant);

            if (!_configDic.ContainsKey(typeName))
            {
                LoadConfig<T>(variant);
            }
            return _configDic[typeName];
        }
    }
}